﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Fetches.Fetch.Utils
{
    public class HtmlUtil
    {
        public static IList<KeyValuePair<string, string>> ExtractUrls(string code)
        {
            var lst = new List<KeyValuePair<string, string>>();
            if (String.IsNullOrWhiteSpace(code))
            {
                return lst;
            }
            string pattern = "href=(\"{1}|'{1})(?<link>[^\\[^>]*?)(\"{1}|'{1})(?<other>[\\s\\S]*?)>+(?<text>.*?)<+?";
            MatchCollection matchs = Regex.Matches(code, pattern, RegexOptions.IgnoreCase);
            foreach (Match m in matchs)
            {
                lst.Add(new KeyValuePair<string, string>(m.Groups["link"].Value, m.Groups["text"].Value));
            }

            return lst;
        }

        /// <summary>
        /// 将html文本转化为 文本内容方法TextNoHTML
        /// </summary>
        /// <param name="Htmlstring">HTML文本值</param>
        /// <returns></returns>
        public static string TextNoHTML(string Htmlstring)
        {
            //删除脚本   
            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
            //删除HTML   
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"([/r/n])[/s]+", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "/", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "/xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "/xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "/xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "/xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(/d+);", "", RegexOptions.IgnoreCase);
            //替换掉 < 和 > 标记
            Htmlstring = Htmlstring.Replace("<", "");
            Htmlstring = Htmlstring.Replace(">", "");
            Htmlstring = Htmlstring.Replace("\r\n", "");
            Htmlstring = Htmlstring.Replace("\r", "");
            Htmlstring = Htmlstring.Replace("\n", "");
            //返回去掉html标记的字符串
            return Htmlstring;
        }

        /// <summary>
        /// 将HTML内容转换成纯文本形式，即去除HTML格式
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string ConvertToText(string source)
        {
            string result;            //remove line breaks,tabs
            result = source.Replace("\r", " ");
            result = result.Replace("\n", " ");
            result = result.Replace("\t", " ");

            //remove the header
            result = Regex.Replace(result, "(<head>).*(</head>)", String.Empty, RegexOptions.IgnoreCase);

            result = Regex.Replace(result, @"<( )*script([^>])*>", "<script>", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<script>).*(</script>)", String.Empty, RegexOptions.IgnoreCase);

            //remove all styles
            result = Regex.Replace(result, @"<( )*style([^>])*>", "<style>", RegexOptions.IgnoreCase); //clearing attributes
            result = Regex.Replace(result, "(<style>).*(</style>)", String.Empty, RegexOptions.IgnoreCase);

            //insert tabs in spaces of <td> tags
            result = Regex.Replace(result, @"<( )*td([^>])*>", " ", RegexOptions.IgnoreCase);

            //insert line breaks in places of <br> and <li> tags
            result = Regex.Replace(result, @"<( )*br( )*>", "\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*li( )*>", "\r", RegexOptions.IgnoreCase);

            //insert line paragraphs in places of <tr> and <p> tags
            result = Regex.Replace(result, @"<( )*tr([^>])*>", "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*p([^>])*>", "\r\r", RegexOptions.IgnoreCase);

            //remove anything thats enclosed inside < >
            result = Regex.Replace(result, @"<[^>]*>", String.Empty, RegexOptions.IgnoreCase);

            //replace special characters:
            result = Regex.Replace(result, @"&", "&", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @" ", " ", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<", "<", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @">", ">", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"&(.{2,6});", String.Empty, RegexOptions.IgnoreCase);

            //remove extra line breaks and tabs
            result = Regex.Replace(result, @" ( )+", " ");
            result = Regex.Replace(result, "(\r)( )+(\r)", "\r\r");
            result = Regex.Replace(result, @"(\r\r)+", "\r\n");

            //remove blank
            result = Regex.Replace(result, @"\s", "");

            return result;
        }

        public static string RemoveComment(string content)
        {
            if (content.Contains("<!--") && content.Contains("-->"))
            {
                do
                {
                    var c1 = content.Substring(0, content.IndexOf("<!--"));
                    var c2 = content.Substring(content.IndexOf("-->") + 3);
                    content = c1 + c2;
                } while (content.Contains("<!--") && content.Contains("-->"));
            }

            return content;
        }

        private static string regexStr = "charset=.*?(?=$|\\s|\\;|\")";
        private static Regex regex = new Regex(regexStr, RegexOptions.IgnoreCase);

        public static Encoding GetEncodingByContentType(string encodingStr)
        {
            Encoding encoding = Encoding.UTF8;
            if (String.IsNullOrEmpty(encodingStr) || encodingStr.Trim().Equals("text/html"))
                return encoding;
            string val = encodingStr;
            var isMatch = regex.IsMatch(encodingStr);
            if (isMatch)
            {
                var match = regex.Match(encodingStr);
                val = match.Value;
                val = val.Replace("charset=", "");
            }
            if (String.IsNullOrEmpty(val)) return encoding;
            val = val.Trim().ToUpper();
            switch (val)
            {
                case "UTF-8":
                case "UTF-7":
                case "UTF-32":
                case "UTF-32BE":
                case "UTF-16":
                case "UTF-16BE":
                case "ASCII":
                case "US-ASCII":
                case "GB2312":
                case "GBK":
                case "UNICODE":
                case "ISO-8859-1":
                    encoding = Encoding.GetEncoding(val);
                    break;
                default:
                    try
                    {
                        encoding = Encoding.GetEncoding(val);
                    }
                    catch (Exception)
                    {
                        //
                    }
                    break;
            }
            return encoding;
        }
    }
}
